Option Explicit

'################################################################
' Discriptor
' 二维数据对象的切片对象 DataFrameSlice 中对各列对象（Series）的引用
' 内部只能通过 `DataFrameSlice#IDataFrame_getCol` 来创建
' 在外部请不要手动创建该对象
'################################################################

Implements IDFSeries

'################################################################
' Field
'################################################################

' 保存 DataFrameSlice 类型的对象
' 用来获取真实数据
Private sliceRef As DataFrameSlice

' 和 sliceRef 相同的引用
' 这里保存成和 IDataFrame 接口类型的引用，以方便操作
Private interfaceRef As IDataFrame

' DataFrame 中被引用的 Series 的索引
Private refSeriesIndex As Integer

'################################################################
' Constructor
'################################################################
Private Sub Class_Initialize()
End Sub

Private Sub Class_Terminate()
    Set sliceRef = Nothing
End Sub

'################################################################
' Init
'################################################################
Public Sub Init(ByRef df As DataFrameSlice, ByRef seriesIndex As Integer)
    Set sliceRef = df
    Set interfaceRef = df
    refSeriesIndex = seriesIndex
End Sub

'################################################################
' Property
'################################################################
' 获取当前一维数据对象中的数据类型
Public Property Get IDFSeries_DataType() As DF_DataType
    IDFSeries_DataType = sliceRef.unsafeGetDelegatedCol(refSeriesIndex).DataType
End Property

' 获取当前一维数据对象中的数据数量
Public Property Get IDFSeries_Size() As Long
    ' 返回 DF 切片中的行数
    IDFSeries_Size = interfaceRef.Size
End Property

' 返回当前数据对象所使用的数据类型处理器
Public Property Get IDFSeries_TypeHandler() As IDFDataTypeHandler
    Set IDFSeries_TypeHandler = sliceRef.unsafeGetDelegatedCol(refSeriesIndex).TypeHandler

End Property

'################################################################
' Private Function
'################################################################


'################################################################
' unsafe Function
' 内置加速方法，为了防止异常，在外部如果没有完善的检测机制不应该主动调用
'################################################################
' 内置取值方法
' 将不会对索引范围进行检查
Public Function IDFSeries_unsafeGetData(ByRef index As Long) As Variant
    ' 通过行 + 列索引定位 DF 上的槽位并获取数据
    IDFSeries_unsafeGetData = interfaceRef.getDataByColIndex(index, refSeriesIndex)
End Function

' 内置设置方法
' 将不会对索引范围进行检查
' 将不会对数据进行标准化处理
Public Sub IDFSeries_unsafeSetData(ByRef index As Long, ByRef val As Variant)
    ' 通过行 + 列索引定位 DF 上的槽位并设置数据
    interfaceRef.setDataByColIndex index, refSeriesIndex, val
End Sub

'################################################################
' Function
'################################################################
'--------------------------------------------------
' 缓存回收
'--------------------------------------------------
Public Sub IDFSeries_cacheCollect()
    ' 直接由原始引用对象进行缓存回收，当前对象内不做额外处理
    sliceRef.unsafeGetDelegatedCol(refSeriesIndex).cacheCollect
End Sub

'--------------------------------------------------
' 数据读写
'--------------------------------------------------

' 检查索引是否在安全范围内
' @param index 需要检查的索引
' @retur Boolean True 在安全范围内; False 在有效范围外
Public Function IDFSeries_hasIndex(ByRef index As Long) As Boolean
    ' 检查 index 是否在 DF 切片中的行范围内
    IDFSeries_hasIndex = (index > 0 And index < interfaceRef.Size)
End Function

' 获取指定索引位置的数据
' 如果指定位置没有数据，则默认返回 Empty
'
' 整型数字 DF_INT 保存成 Long 或 Integer 型
' 日期 DF_DATE 保存成字符串类型
' 时间 DF_TIME 保存成字符串类型
' 时间戳 DF_TIMESTAMP 保存成字符串类型
'
' @param index 数据索引
' @return 指定索引位置上的数据
Public Function IDFSeries_getData(ByRef index As Long) As Variant
    ' 通过行 + 列索引定位 DF 上的槽位并获取数据
    IDFSeries_getData = interfaceRef.getDataByColIndex(index, refSeriesIndex)
End Function

' 设置指定索引位置的数据
'
' 整型数字 DF_INT 返回 Long 或 Integer 型
' 日期 DF_DATE 返回字符串类型
' 时间 DF_TIME 返回字符串类型
' 时间戳 DF_TIMESTAMP 返回字符串类型
'
' @param index 数据索引
' @param val 需要设置的数据
Public Sub IDFSeries_setData(ByRef index As Long, ByRef val As Variant)
    ' 通过行 + 列索引定位 DF 上的槽位并设置数据
    interfaceRef.setDataByColIndex index, refSeriesIndex
End Sub

'--------------------------------------------------
' CRUD
'--------------------------------------------------

' 向末尾新增一个数据
'
' @param val 需要设置的数据
Public Sub IDFSeries_appendData(ByRef val As Variant)
    ' 不支持该操作，以防止对修改 DF 切片对象产生的不一致
    ' 这类操作应该从外部由 DF 切片对象进行统一控制
    Err.Raise 10900, Description:="DataFrameSliceSeriesRef does not support method [appendData]"
End Sub

' 向末尾新增一个或多个空数据
'
' @param count 需要添加的空数据的数量，默认=1
Public Sub IDFSeries_appendEmpty(Optional ByRef count As Long = 1)
    ' 不支持该操作，以防止对修改 DF 切片对象产生的不一致
    ' 这类操作应该从外部由 DF 切片对象进行统一控制
    Err.Raise 10900, Description:="DataFrameSliceSeriesRef does not support method [appendEmpty]"
End Sub

' 删除指定索引位置的数据。只删除当前对象内的数据
' 该方法会导致内部数据产生移动，如果数据量很大，将会花费大量时间
'
' @param index 数据索引
Public Sub IDFSeries_delData(ParamArray indexes() As Variant)
    ' 不支持该操作，以防止对修改 DF 切片对象产生的不一致
    ' 这类操作应该从外部由 DF 切片对象进行统一控制
    Err.Raise 10900, Description:="DataFrameSliceSeriesRef does not support method [delData]"
End Sub

' 删除指定索引位置的数据。只删除当前对象内的数据
' 该方法会导致内部数据产生移动，如果数据量很大，将会花费大量时间
'
' @param index 数据索引
Public Sub IDFSeries_delDataByIndexArray(ByRef indexes As Variant)
    ' 不支持该操作，以防止对修改 DF 切片对象产生的不一致
    ' 这类操作应该从外部由 DF 切片对象进行统一控制
    Err.Raise 10900, Description:="DataFrameSliceSeriesRef does not support method [delDataByIndexArray]"
End Sub

' 删除指定索引位置的数据。如果当前是引用对象，也会直接删除原始对象中的数据
' 该方法会导致内部数据产生移动，如果数据量很大，将会花费大量时间
'
' @param index 数据索引
Public Sub IDFSeries_deepDelData(ParamArray indexes() As Variant)
    ' 不支持该操作，以防止对修改 DF 切片对象产生的不一致
    ' 这类操作应该从外部由 DF 切片对象进行统一控制
    Err.Raise 10900, Description:="DataFrameSliceSeriesRef does not support method [deepDelData]"
End Sub

' 删除指定索引位置的数据。如果当前是引用对象，也会直接删除原始对象中的数据
' 该方法会导致内部数据产生移动，如果数据量很大，将会花费大量时间
'
' @param index 数据索引
Public Sub IDFSeries_deepDelDataByIndexArray(ByRef indexes As Variant)
    ' 不支持该操作，以防止对修改 DF 切片对象产生的不一致
    ' 这类操作应该从外部由 DF 切片对象进行统一控制
    Err.Raise 10900, Description:="DataFrameSliceSeriesRef does not support method [deepDelDataByIndexArray]"
End Sub

' 拷贝指定索引的数据到末尾
'
' @param index 数据索引
' @optional-param needDescriptor 如果数据存在描述符，是否需要拷贝，默认=False
Public Sub IDFSeries_copyAndAppend(ByRef index As Long, Optional ByRef needDescriptor As Boolean=False)
    ' 不支持该操作，以防止对修改 DF 切片对象产生的不一致
    ' 这类操作应该从外部由 DF 切片对象进行统一控制
    Err.Raise 10900, Description:="DataFrameSliceSeriesRef does not support method [copyAndAppend]"
End Sub

' 使用指定数据填充内部所有数据是 Empty 的槽位
'
' 如果参数 val 无法被标准化为与当前 IDFSeries 类型相同的数据，将不会进行数据填充
'
' 对于切片类型，应该只填充引用的那些槽位，未引用的槽位不应该进行修改
'
' @param val 用来填充的数据
Public Sub IDFSeries_fillEmptySlot(ByRef val As Variant)
    ' 1. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 2. 标准化填充数据
    Dim fillVal As Variant
    fillVal = dataTypeHandler.normalize(val)

    ' 3. 如果标准化失败（参数 val 无法和当前 IDFSeries 的类型统一），则放弃填充操作
    If IsEmpty(fillVal) Then
        End Sub
    End If

    ' 3. 遍历整个对象，搜索引用中的 Empty 槽位，并填充数据
    Dim i As Long
    For i = 0 To (interfaceRef.Size - 1)
        If IsEmpty(IDFSeries_unsafeGetData(i)) Then
            IDFSeries_unsafeSetData i, fillVal
        End If
    Next
End Sub
'--------------------------------------------------
' 数据计算
'--------------------------------------------------
'===========
' 基础类型计算
'===========
' 对所有数据进行指定方式的运算
'
' @param funcStr 运算函数名字符串
'        需要提供形式为 Function method(ByRef origin As Variant) As Variant 的方法
Public Sub IDFSeries_exec(ByRef funcStr As String)
    ' 1. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 2. 获取各索引上的真实值，计算后再重新保存
    Dim i As Long
    For i = 0 To (interfaceRef.Size - 1)
        IDFSeries_unsafeSetData _
            i, _
            dataTypeHandler.normalize(Application.Run(funcStr, IDFSeries_unsafeGetData(i)))
    Next
End Sub

' 对所有数据进行指定方式的运算
'
' @param v 运算数据
' @param funcStr 运算函数名字符串
'        需要提供形式为 Function method(ByRef origin As Variant, ByRef computeVal As Variant) As Variant 的方法
Public Sub IDFSeries_compute(ByRef v As Variant, ByRef funcStr As String)
    ' 1. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 2. 获取各索引上的真实值，计算后再重新保存
    Dim i As Long
    For i = 0 To (interfaceRef.Size - 1)
        IDFSeries_unsafeSetData i, dataTypeHandler.normalize( _
            Application.Run(funcStr, IDFSeries_unsafeGetData(i), v) _
        )
    Next
End Sub

' 对所有数据进行加法运算
'
' 整型，做加法
' 浮点型，做加法
' 字符串，将会直接做字符串连接
' 日期，以天为单位做加法
' 时间，以秒为单位做加法
' 时间戳，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 布尔型，将不会做处理，如果有需要请使用 compute 或 exec 方法
'
' @param v 运算数据
Public Sub IDFSeries_add(ByRef v As Variant)
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 如果当前类型不支持该操作，则立刻停止
    If dataTypeHandler.SupportAdd = False Then
        Exit Sub
    End If

    ' 2. 将运算数据转换成标准计算类型数据
    Dim computeData As Variant
    computeData = dataTypeHandler.normalizeComputeData(v)

    ' 3. 如果计算数据是 Empty，则不做计算
    If IsEmpty(computeData) Then
        Exit Sub
    End If

    ' 4. 对所有数据进行计算
    Dim i As Long
    For i = 0 To interfaceRef.Size - 1
        IDFSeries_unsafeSetData _
            i, _
            dataTypeHandler.add( _
                IDFSeries_unsafeGetData(i), _
                computeData _
            )
    Next
End Sub

' 对所有数据进行减法运算
'
' 整型，做减法
' 浮点型，做减法
' 字符串，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 日期，以天为单位做减法
' 时间，以秒为单位做减法
' 时间戳，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 布尔型，将不会做处理，如果有需要请使用 compute 或 exec 方法
'
' @param v 运算数据
Public Sub IDFSeries_subtract(ByRef v As Variant)
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 如果当前类型不支持该操作，则立刻停止
    If dataTypeHandler.SupportSubtract = False Then
        Exit Sub
    End If

    ' 2. 将运算数据转换成标准计算类型数据
    Dim computeData As Variant
    computeData = dataTypeHandler.normalizeComputeData(v)

    ' 3. 如果计算数据是 Empty，则不做计算
    If IsEmpty(computeData) Then
        Exit Sub
    End If

    ' 4. 对所有数据进行计算
    Dim i As Long
    For i = 0 To interfaceRef.Size - 1
        IDFSeries_unsafeSetData _
            i, _
            dataTypeHandler.subtract( _
                IDFSeries_unsafeGetData(i), _
                computeData _
            )
    Next
End Sub

' 对所有数据进行乘法运算
'
' 整型，做乘法
' 浮点型，做乘法
' 字符串，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 日期，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 时间，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 时间戳，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 布尔型，将不会做处理，如果有需要请使用 compute 或 exec 方法
'
' @param v 运算数据
Public Sub IDFSeries_multiply(ByRef v As Variant)
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 如果当前类型不支持该操作，则立刻停止
    If dataTypeHandler.SupportMultiply = False Then
        Exit Sub
    End If

    ' 2. 将运算数据转换成标准计算类型数据
    Dim computeData As Variant
    computeData = dataTypeHandler.normalizeComputeData(v)

    ' 3. 如果计算数据是 Empty，则不做计算
    If IsEmpty(computeData) Then
        Exit Sub
    End If

    ' 4. 对所有数据进行计算
    Dim i As Long
    For i = 0 To interfaceRef.Size - 1
        IDFSeries_unsafeSetData _
            i, _
            dataTypeHandler.multiply( _
                IDFSeries_unsafeGetData(i), _
                computeData _
            )
    Next
End Sub

' 对所有数据进行除法运算
'
' 整型，做除法
' 浮点型，做除法
' 字符串，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 日期，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 时间，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 时间戳，将不会做处理，如果有需要请使用 compute 或 exec 方法
' 布尔型，将不会做处理，如果有需要请使用 compute 或 exec 方法
'
' @param v 运算数据
Public Sub IDFSeries_divide(ByRef v As Variant)
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 如果当前类型不支持该操作，则立刻停止
    If dataTypeHandler.SupportDivide = False Then
        Exit Sub
    End If

    ' 2. 将运算数据转换成标准计算类型数据
    Dim computeData As Variant
    computeData = dataTypeHandler.normalizeComputeData(v)

    ' 3. 如果计算数据是 Empty，则不做计算
    If IsEmpty(computeData) Then
        Exit Sub
    End If

    ' 4. 对所有数据进行计算
    Dim i As Long
    For i = 0 To interfaceRef.Size - 1
        IDFSeries_unsafeSetData _
            fieldData(i), _
            dataTypeHandler.divide( _
                IDFSeries_unsafeGetData(i), _
                computeData _
            )
    Next
End Sub

'===========
' 和其他 Series 类型做计算
'===========
' 和其他 Series 做加法运算，计算结果合并到当前 Series
'
' @param desc 运算 Series
Public Sub IDFSeries_mergeAdd(ByRef desc As Series)
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    dataTypeHandler.mergeAdd Me, desc
End Sub

' 和其他 Series 做减法运算，计算结果合并到当前 Series
'
' @param desc 运算 Series
Public Sub IDFSeries_mergeSubtract(ByRef desc As Series)
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    dataTypeHandler.mergeSubtract Me, desc
End Sub

' 和其他 Series 做乘法运算，计算结果合并到当前 Series
'
' @param desc 运算 Series
Public Sub IDFSeries_mergeMultiply(ByRef desc As Series)
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    dataTypeHandler.mergeMultiply Me, desc
End Sub

' 和其他 Series 做除法运算，计算结果合并到当前 Series
'
' @param desc 运算 Series
Public Sub IDFSeries_mergeDivide(ByRef desc As Series)
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    dataTypeHandler.mergeDivide Me, desc
End Sub

'--------------------------------------------------
' 比较运算
'--------------------------------------------------
'=============
' 生成 Boolean IDFSeries
'=============
' 和指定运算符进行比较，返回一个和当前 series 相同的 Boolean 型的 series
' =
Public Function IDFSeries_eq(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_eq = dataTypeHandler.eqForSeries(Me, v)
End Function

' !=
Public Function IDFSeries_ne(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_ne = dataTypeHandler.neForSeries(Me, v)
End Function

' >
Public Function IDFSeries_gt(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_gt = dataTypeHandler.gtForSeries(Me, v)
End Function

' <
Public Function IDFSeries_lt(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_lt = dataTypeHandler.ltForSeries(Me, v)
End Function

' >=
Public Function IDFSeries_ge(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_ge = dataTypeHandler.geForSeries(Me, v)
End Function

' <=
Public Function IDFSeries_le(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_le = dataTypeHandler.leForSeries(Me, v)
End Function

' In()
Public Function IDFSeries_inVals(ByRef vs As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_inVals = dataTypeHandler.inValsForSeries(Me, vs)
End Function

' between
Public Function IDFSeries_between(ByRef left As Variant, ByRef right As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_between = dataTypeHandler.betweenForSeries(Me, left, right)
End Function

'=============
' 生成 Series ，保存所有结果为 true 的数据
'=============
' =
Public Function IDFSeries_eqToSeries(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_eqToSeries = dataTypeHandler.eqToSeriesForSeries(Me, v)
End Function
' !=
Public Function IDFSeries_neToSeries(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_neToSeries = dataTypeHandler.neToSeriesForSeries(Me, v)
End Function
' >
Public Function IDFSeries_gtToSeries(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_gtToSeries = dataTypeHandler.gtToSeriesForSeries(Me, v)
End Function
' <
Public Function IDFSeries_ltToSeries(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_gtToSeries = dataTypeHandler.ltToSeriesForSeries(Me, v)
End Function
' >=
Public Function IDFSeries_geToSeries(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_geToSeries = dataTypeHandler.geToSeriesForSeries(Me, v)
End Function
' <=
Public Function IDFSeries_leToSeries(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_leToSeries = dataTypeHandler.leToSeriesForSeries(Me, v)
End Function
' In()
Public Function IDFSeries_inValsToSeries(ByRef vs As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_inValsToSeries = dataTypeHandler.inValsToSeriesForSeries(Me, vs)
End Function
' between
Public Function IDFSeries_betweenToSeries(ByRef left As Variant, ByRef right As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_betweenToSeries = dataTypeHandler.betweenToSeriesForSeries(Me, left, right)
End Function

'=============
' 生成 Series 切片，保存所有结果为 true 的数据的引用
'=============
' =
Public Function IDFSeries_eqToSlice(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_eqToSlice = dataTypeHandler.eqToSliceForSeries(Me, v)
End Function
' !=
Public Function IDFSeries_neToSlice(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_neToSlice = dataTypeHandler.neToSliceForSeries(Me, v)
End Function
' >
Public Function IDFSeries_gtToSlice(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_gtToSlice = dataTypeHandler.gtToSliceForSeries(Me, v)
End Function
' <
Public Function IDFSeries_ltToSlice(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_ltToSlice = dataTypeHandler.ltToSliceForSeries(Me, v)
End Function
' >=
Public Function IDFSeries_geToSlice(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_geToSlice = dataTypeHandler.geToSliceForSeries(Me, v)
End Function
' <=
Public Function IDFSeries_leToSlice(ByRef v As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_leToSlice = dataTypeHandler.leToSliceForSeries(Me, v)
End Function
' In()
Public Function IDFSeries_inValsToSlice(ByRef vs As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_inValsToSlice = dataTypeHandler.inValsToSliceForSeries(Me, vs)
End Function
' between
Public Function IDFSeries_betweenToSlice(ByRef left As Variant, ByRef right As Variant) As IDFSeries
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 执行计算
    Set IDFSeries_betweenToSlice = dataTypeHandler.betweenToSliceForSeries(Me, left, right)
End Function

'=============
' 检查某一索引的元素是否符合规则
'=============
'Public Function eqElem(ByRef index As Long, ByRef v As Variant) As Boolean
'End Function
'Public Function neElem(ByRef index As Long, ByRef v As Variant) As Boolean
'End Function
'Public Function gtElem(ByRef index As Long, ByRef v As Variant) As Boolean
'End Function
'Public Function ltElem(ByRef index As Long, ByRef v As Variant) As Boolean
'End Function
'Public Function geElem(ByRef index As Long, ByRef v As Variant) As Boolean
'End Function
'Public Function leElem(ByRef index As Long, ByRef v As Variant) As Boolean
'End Function
'Public Function inValsElem(ByRef index As Long, ByRef vs As Variant) As Boolean
'End Function
'Public Function betweenElem(ByRef index As Long, ByRef left As Variant, ByRef right As Variant) As Boolean
'End Function


'--------------------------------------------------
' 聚合运算
'--------------------------------------------------
' 返回 Series 中的最大值
'
' 如果 Series 中没有数据，则返回 Empty
' 如果当前 Series 的类型不支持 max 运算，则返回 Empty
'
Public Function IDFSeries_max() As Variant
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 如果当前类型不支持该操作，则立刻停止
    If dataTypeHandler.SupportMax = False Then
        Exit Function
    End If

    ' 2. 执行计算
    IDFSeries_max = dataTypeHandler.max(Me)
End Function

' 返回 Series 中的最小值
'
' 如果 Series 中没有数据，则返回 Empty
' 如果当前 Series 的类型不支持 min 运算，则返回 Empty
'
Public Function IDFSeries_min() As Variant
    ' 0. 获取类型处理器
    Dim dataTypeHandler As IDFDataTypeHandler
    Set dataTypeHandler = IDFSeries_TypeHandler

    ' 1. 如果当前类型不支持该操作，则立刻停止
    If dataTypeHandler.SupportMax = False Then
        Exit Function
    End If

    ' 2. 执行计算
    IDFSeries_max = dataTypeHandler.min(Me)
End Function

'--------------------------------------------------
' 数据描述符
'--------------------------------------------------

' 获取某个数据的描述器
' 如果不存在，则返回 Nothing
'
' @param index 数据索引
' @optional-param needCreate 如果描述信息对象不存在是否需要进行创建。默认值=False
' @return IDFDescriptor 数据描述器
Public Function IDFSeries_getDataDescriptor(ByRef index As Long, Optional ByRef needCreate As Boolean = False) As IDFDescriptor
    Set IDFSeries_getDataDescriptor = interfaceRef.getDataDescriptor(index, refSeriesIndex, needCreate)
End Function

'--------------------------------------------------
' 切片操作
'--------------------------------------------------
' 切片
' @optional-param start Long 起始位置
' @optional-param stop Long 终止位置(最终不会包含 stop 的索引)
' @optional-param step Long 步长
Public Function IDFSeries_slice(Optional startIdx As Variant, Optional ByRef stopIdx As Variant, Optional ByRef step As Variant=1) As IDFSeries
    Dim result As DFSeriesSlice
    Set result = New DFSeriesSlice
    result.Init Me, startIdx, stopIdx, step

    Set IDFSeries_slice = result
End Function

' 使用指定索引创建切片
' 如果没有指定任何索引，则保留对所有数据的引用
' @param-array indexes 需要的真实索引
Public Function IDFSeries_sliceByIndexes(ParamArray indexes() As Variant) As IDFSeries
    Dim ies As Variant
    ies = indexes

    Set IDFSeries_sliceByIndexes = IDFSeries_sliceByIndexArray(ies)
End Function

' 使用指定索引数组创建切片
' 如果数组长度为 0，则保留对所有数据的引用
' @param indexes 需要的真实索引
Public Function IDFSeries_sliceByIndexArray(ByRef indexes As Variant) As IDFSeries
    Dim result As DFSeriesSlice
    Set result = New DFSeriesSlice
    result.InitByIndexArray Me, indexes

    Set IDFSeries_sliceByIndexArray = result
End Function

'--------------------------------------------------
' 输出操作
'--------------------------------------------------

' 将 Series 中的内容输出到控制台
' 每个数据输出为一行
' Empty 将会以字符串 "@@EMPTY@@" 的形式输出
'
' @optional-param startIdx 输出的起始行(包括这一行，从 0 开始)
'                          只支持 0、正数，如果输入了一个负数，则自动使用 0
'                          如果 startIdx > endIdx，则不输出任何数据
' @optional-param endIdx 输出的结束行(包括这一行，从 0 开始)
'                          只支持 0、正数，如果输入了一个负数，则自动使用最大行索引
Public Sub IDFSeries_printToConsole(Optional ByRef startIdx As Long = 0, _
    Optional ByRef endIdx As Long = -1)

    ' 1. 如果当前 DF 没有任何行，则立刻结束
    Dim dataSize As Long
    dataSize = interfaceRef.Size

    If dataSize = 0 Then
        Exit Sub
    End If

    ' 2. 确认参数
    Dim realStartIdx As Long
    Dim realEndIdx As Long
    If startIdx < 0 Then
        realStartIdx = 0
    Else
        If startIdx >= dataSize Then
            realStartIdx = dataSize - 1
        Else
            realStartIdx = startIdx
        End If
    End If
    If endIdx < 0 Then
        realEndIdx = dataSize - 1
    Else
        If endIdx >= dataSize Then
            realEndIdx = dataSize - 1
        Else
            realEndIdx = endIdx
        End If
    End If

    ' 如果 startIdx > endIdx，则不输出任何数据
    If realStartIdx > realEndIdx Then
        Exit Sub
    End If

    ' 3. 按行输出内容
    Dim i As Long
    Dim temp As Variant
    For i = realStartIdx To realEndIdx
        temp = interfaceRef.getDataByColIndex(i, refSeriesIndex)

        If IsEmpty(temp) Then
            Debug.Print DFHelper.EMPTY_STR_IN_CONSOLE
        Else
            Debug.Print temp & ""
        End If
    Next
End Sub